package gwtool.gui;

import gwtool.backend.DataSetController;
import gwtool.backend.updater.UpdateCheck;
import gwtool.container.Benutzter;
import gwtool.container.DataSet;
import gwtool.gui.components.JButtonTabComponent;
import gwtool.gui.components.MyProgressbar;
import gwtool.gui.dataSetTable.DataSetTableController;
import gwtool.gui.dataSetView.DataSetViewController;
import gwtool.gui.konfliktmanager.KonfliktController;
import gwtool.gui.login.LoginController;
import gwtool.gui.ueberDialog.UeberController;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
import javax.swing.WindowConstants;

public class MainController implements ActionListener {

	private static String version = "0.61 Alpha";

	private static String xmlversion = "4";

	private static MainController mainController;

	private JFrame jframe = null;

	private DataSetController dataController;

	private DataSetTableController tableController = null;

	private boolean startMode = true;

	private Map<DataSet, DataSetViewController> tabMap = new HashMap<>();

	private HauptFensterPanel hauptPanel;

	private MainController() {

		mainController = this;
		dataController = new DataSetController();
	}

	public static MainController getInstance() {

		if (mainController == null) {
			mainController = new MainController();
		}
		return mainController;
	}

	public void createLoginANDGUI() {

		jframe = new JFrame();
		new UpdateCheck(null, false);
		Benutzter benutzer = null;
		final MyProgressbar dialog = new MyProgressbar(null);
		dialog.setLocationRelativeTo(null);
		dialog.setSize(200, 50);
		dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		dialog.setTitle("Prüfe Logindaten");
		boolean passWrong = false;
		do {
			dialog.setVisible(false);
			if (passWrong) {
				JOptionPane.showMessageDialog(null, "Logindaten nicht gültig!");
			}
			LoginController controller = new LoginController(version);
			benutzer = controller.getBenutzter();
			dialog.setVisible(true);
			passWrong = true;
		} while (!dataController.loginDatenKorrekt(benutzer));
		hauptPanel = new HauptFensterPanel(this);
		jframe.add(hauptPanel);
		jframe.setJMenuBar(hauptPanel.getMenuBar_1());
		jframe.setSize(1100, 700);
		jframe.setLocationRelativeTo(null);
		jframe.setVisible(true);
		updateGui();
		dialog.dispose();
		addWindowAdapter();
	}

	public static DataSet handelConflickt(DataSet localItem, DataSet onlineItem) {

		KonfliktController manager = new KonfliktController(localItem, onlineItem);
		return manager.getMergedSet();
	}

	@Override
	public void actionPerformed(ActionEvent e) {

		if (e.getSource() == hauptPanel.getMntmberGwtool()) {
			new UeberController();
		}
		if (e.getSource() == hauptPanel.getMntmDrucken()) {
			JOptionPane
					.showMessageDialog(
							null,
							"<html>STRG gedrückt halten und so mehrere Einträge wählen.<br> Wenn man nun unten mit dem Knopf druckt, werden alle Einträge aneinander gehängt.");
		}
		if (e.getSource() == hauptPanel.getMntmLscheLokaleDateien()) {
			getDataController().clearLocalCache();
			JOptionPane.showMessageDialog(null, "Die Dateien wurden gelöscht!");
		}
		if (e.getSource() == hauptPanel.getMntmSchlieen()) {
			schliessen();
		}
	}

	/**
	 * Anzeigen und wenn nicht vorhanden erzeugen
	 */
	public void showDataSetTab(DataSet set) {

		JTabbedPane tabbedpane = hauptPanel.getTabbedPane();
		DataSetViewController s = tabMap.get(set);
		if (s == null) {
			DataSetViewController view = new DataSetViewController(set, -1);
			tabMap.put(set, view);
			tabbedpane.addTab(view.getTabBezeichner(), view.getPanel());
			s = tabMap.get(set);
			tabbedpane.setTabComponentAt(tabbedpane.indexOfComponent(s.getPanel()),
					new JButtonTabComponent(tabbedpane, view));
		}
		s = tabMap.get(set);
		tabbedpane.setSelectedIndex(tabbedpane.indexOfComponent(s.getPanel()));
	}

	public void closeTab(DataSet set) {

		JTabbedPane tabbedpane = hauptPanel.getTabbedPane();
		DataSetViewController s = tabMap.get(set);
		if (s != null) {
			tabbedpane.removeTabAt(tabbedpane.indexOfComponent(s.getPanel()));
			tabMap.remove(set);
		}
	}

	public void alleSpeichern() {

		for (DataSet s : tabMap.keySet()) {
			DataSetViewController c = tabMap.get(s);
			if (c.hasChanges()) {
				c.speichern();
			}
		}
	}

	public void closeAllTabs() {

		if (gibtEsNichtGespeicherteAenderungen()) {
			int ans = JOptionPane.showConfirmDialog(hauptPanel,
					"<html>Sollen die Änderungen vor dem Hochladen gespeichert werden? <br> Sie gehen sonst verloren!",
					"Speichern?", JOptionPane.YES_NO_OPTION);
			if (ans == JOptionPane.YES_OPTION) {
				alleSpeichern();
			}
		}
		JTabbedPane tabbedpane = hauptPanel.getTabbedPane();
		tabbedpane.removeAll();
		tabMap.clear();
	}

	public boolean gibtEsNichtGespeicherteAenderungen() {

		for (DataSet s : tabMap.keySet()) {
			DataSetViewController c = tabMap.get(s);
			if (c.hasChanges()) {
				return true;
			}
		}
		return false;
	}

	private void sollGespeichertWerdenDialog() {

		if (gibtEsNichtGespeicherteAenderungen()) {
			int ans = JOptionPane.showConfirmDialog(hauptPanel,
					"<html>Sollen die Änderungen gespeichert werden?<br>Sie gehen sonst verloren!", "Speichern?",
					JOptionPane.YES_NO_OPTION);
			if (ans == JOptionPane.YES_OPTION) {
				alleSpeichern();
			}
		}
	}

	private void commitDataZumServerWithShutdown() {
		getDataController().getComm().startOnlineUpdate(true);
	}

	public void updateGui() {

		if (tableController != null && hauptPanel != null) {
			tableController.getModel().aktualisiere();
			tableController.fillGruppenComboBox();
			JTabbedPane tabbedpane = hauptPanel.getTabbedPane();
			for (DataSet index : tabMap.keySet()) {
				DataSetViewController s = tabMap.get(index);
				tabbedpane.setTitleAt(tabbedpane.indexOfComponent(s.getPanel()), s.getTabBezeichner());
			}
		}
	}

	public DataSetController getDataController() {

		return dataController;
	}

	public void setTableController(DataSetTableController tableController) {

		this.tableController = tableController;
	}

	private void addWindowAdapter() {

		jframe.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {

				schliessen();
			}

			@Override
			public void windowClosed(WindowEvent e) {

			}
		});
	}

	private void schliessen() {

		sollGespeichertWerdenDialog();
		jframe.dispose();
		commitDataZumServerWithShutdown();
	}

	public JFrame getJFrame() {

		return jframe;
	}

	public static String getVersion() {

		return version;
	}

	public static String getXmlversion() {

		return xmlversion;
	}

	public boolean isStartMode() {

		return startMode;
	}

	public void setStartMode(boolean startMode) {

		this.startMode = startMode;
	}
}
